package com.lyl.label.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyl.label.dao.LabelDao;
import com.lyl.label.model.entity.Label;
import com.lyl.label.service.LabelService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 标签表(Label)表服务实现类
 *
 * @author makejava
 * @since 2022-06-19 16:25:42
 */
@Service("labelService")
public class LabelServiceImpl extends ServiceImpl<LabelDao, Label> implements LabelService {

    @Override
    public List<Label> tree() {
        return getTree(list());
    }

    @Override
    public List<Label> treeByDesc() {
        return getTreeByDesc(list());
    }

    public List<Label> getTreeByDesc(List<Label> list){
        if (CollUtil.isEmpty(list)){
            return ListUtil.empty();
        }
        Map<Integer, List<Label>> levelMap = list.stream().collect(Collectors.groupingBy(Label::getLevel));
        List<Integer> levelList = levelMap.keySet().stream().sorted().collect(Collectors.toList());
        Map<Integer, List<Label>> childMap;
        while (levelList.size() > 0){
            Integer level = levelList.remove(levelList.size() - 1);
            List<Label> childLabels = levelMap.get(level);
            childMap = childLabels.stream().collect(Collectors.groupingBy(Label::getParentId));
            List<Label> labelList = levelMap.get(level - 1);
            if (CollUtil.isEmpty(labelList)){
                return childLabels;
            }
            for (Label label : labelList) {
                label.setChildren(childMap.getOrDefault(label.getId(),ListUtil.empty()));
            }
        }
        return ListUtil.empty();
    }

    public List<Label> getTree(List<Label> list){
        if (CollUtil.isEmpty(list)){
            return ListUtil.empty();
        }
        Map<Integer, List<Label>> levelMap = list.stream().collect(Collectors.groupingBy(Label::getLevel));
        return getTree(levelMap,0);
    }

    private List<Label> getTree(Map<Integer, List<Label>> levelMap,Integer level){
        List<Label> labelList = levelMap.get(level);
        if (CollUtil.isEmpty(labelList)){
            return ListUtil.empty();
        }
        List<Label> childLabelList = getTree(levelMap,level + 1);
        Map<Integer, List<Label>> childMap = childLabelList.stream().collect(Collectors.groupingBy(Label::getParentId));
        for (Label label : labelList) {
            label.setChildren(childMap.getOrDefault(label.getId(), ListUtil.empty()));
        }
        return labelList;
    }
}
